﻿namespace ImageProcessing.ImageProcessor
{
    using System;
    using System.Collections.Generic;
    using System.Linq;
    using System.Text;

    /// <summary>
    /// Point Structure
    /// </summary>
    public struct Mypoint
    {
        /// <summary>
        ///  Co-ordinate x
        /// </summary>
        public int X;

        /// <summary>
        /// Co-ordinate y
        /// </summary>
        public int Y;
    }

    /// <summary>
    /// TODO: Update summary.
    /// </summary>
    public static class IMG_NotchFilter
    {
        /// <summary>
        /// Notching Method
        /// </summary>
        /// <param name="orig_img">Orginal Image</param>
        /// <param name="radiusNode">Node Radius</param>
        /// <param name="pointXnode">X node</param>
        /// <param name="pointYnode">Y node</param>
        /// <returns>Notched Image</returns>
        public static Entities.IMG_Image IMG_Notch(Entities.IMG_Image orig_img, int radiusNode, int pointXnode, int pointYnode)
        {
            try
            {
                int img_Width = orig_img.Width;
                int img_Height = orig_img.Height;
                IMG_FourierClass img_PreNormalization = new IMG_FourierClass(orig_img);
                img_PreNormalization.IMG_CalculateFourier();
                Entities.IMG_Image img_returned = new Entities.IMG_Image(img_Width, img_Height);
                Entities.IMG_Image img_restored = new Entities.IMG_Image(img_Width, img_Height);

                double u0 = img_Width / 2;
                double v0 = img_Height / 2;
                
                Mypoint givenPoint = new Mypoint();
                givenPoint.X = pointXnode;
                givenPoint.Y = pointYnode;

                Mypoint symmetricPoint = new Mypoint();
                symmetricPoint.X = -pointXnode;
                symmetricPoint.Y = pointYnode;

                for (int dim_j = 0; dim_j < img_Height; dim_j++)
                {
                    for (int dim_i = 0; dim_i < img_Width; dim_i++)
                    {
                        double u1 = u0 + pointXnode;
                        double v1 = v0 + pointYnode;
                        double u2 = u0 - pointXnode;
                        double v2 = v0 - pointYnode;
                        double distance1 = Math.Sqrt((Math.Pow(dim_i - u1, 2) + Math.Pow(dim_j - v1, 2)));
                        double distance2 = Math.Sqrt((Math.Pow(dim_i - u2, 2) + Math.Pow(dim_j - v2, 2)));

                        if (distance1 > radiusNode && distance2 > radiusNode)
                        {
                        }
                        else
                        {
                            img_PreNormalization.RealRed[dim_i, dim_j] = 0;
                            img_PreNormalization.ImagRed[dim_i, dim_j] = 0;
                            img_PreNormalization.RealGreen[dim_i, dim_j] = 0;
                            img_PreNormalization.ImagGreen[dim_i, dim_j] = 0;
                            img_PreNormalization.RealBlue[dim_i, dim_j] = 0;
                            img_PreNormalization.ImagBlue[dim_i, dim_j] = 0;
                        }
                    }
                }

                img_restored = img_PreNormalization.RestoreImage();
                img_returned = IMG_Normalize.IMG_NormalizeImage(img_restored);
                return img_returned;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }

        /// <summary>
        /// IMs the g_ notch pass.
        /// </summary>
        /// <param name="orig_img">The orig_img.</param>
        /// <param name="radiusNode">The radius node.</param>
        /// <param name="pointXnode">The point xnode.</param>
        /// <param name="pointYnode">The point ynode.</param>
        /// <returns>the edited image</returns>
        public static Entities.IMG_Image IMG_NotchPass(Entities.IMG_Image orig_img, int radiusNode, int pointXnode, int pointYnode)
        {
            try
            {
                int img_Width = orig_img.Width;
                int img_Height = orig_img.Height;
                IMG_FourierClass img_PreNormalization = new IMG_FourierClass(orig_img);
                img_PreNormalization.IMG_CalculateFourier();
                Entities.IMG_Image img_returned = new Entities.IMG_Image(img_Width, img_Height);
                Entities.IMG_Image img_restored = new Entities.IMG_Image(img_Width, img_Height);

                double u0 = img_Width / 2;
                double v0 = img_Height / 2;               

                Mypoint givenPoint = new Mypoint();
                givenPoint.X = pointXnode;
                givenPoint.Y = pointYnode;

                Mypoint symmetricPoint = new Mypoint();
                symmetricPoint.X = -pointXnode;
                symmetricPoint.Y = pointYnode;

                for (int dim_j = 0; dim_j < img_Height; dim_j++)
                {
                    for (int dim_i = 0; dim_i < img_Width; dim_i++)
                    {
                        double u1 = u0 + pointXnode;
                        double v1 = v0 + pointYnode;
                        double u2 = u0 - pointXnode;
                        double v2 = v0 - pointYnode;
                        double distance1 = Math.Sqrt((Math.Pow(dim_i - u1, 2) + Math.Pow(dim_j - v1, 2)));
                        double distance2 = Math.Sqrt((Math.Pow(dim_i - u2, 2) + Math.Pow(dim_j - v2, 2)));

                        if (distance1 > radiusNode && distance2 > radiusNode)
                        {                            
                            img_PreNormalization.RealRed[dim_i, dim_j] = 0;
                            img_PreNormalization.ImagRed[dim_i, dim_j] = 0;
                            img_PreNormalization.RealGreen[dim_i, dim_j] = 0;
                            img_PreNormalization.ImagGreen[dim_i, dim_j] = 0;
                            img_PreNormalization.RealBlue[dim_i, dim_j] = 0;
                            img_PreNormalization.ImagBlue[dim_i, dim_j] = 0;
                        }
                    }
                }

                img_restored = img_PreNormalization.RestoreImage();
                img_returned = IMG_Normalize.IMG_NormalizeImage(img_restored);
                return img_returned;
            }
            catch (Exception img_Ex)
            {
                Logger.LogException(img_Ex);
                throw;
            }
        }
    }
}
